﻿#include "logprintmgr.h"
#include "logcustprinter.hpp"
#include "loghand.h"
#include "logimpl.h"
#include "logfileprinter.h"
#include "logconslprinter.hpp"
#include <thread>
#define  MAX_SIZE    1024*10
NAMESPACE_USE;
thread_local LoggerHand hand_;
void addDevice(Device* dev) {
    LoggerCustPrinterMgr::getInstance().addDevcie(dev);
}
void setLogConfig (const char* save_dir,size_t max_file_size,bool open_log_que) {
    LoggerFilePrinter::getInstance().setLogSaveDir(save_dir,max_file_size);
    LoggerPrintMgr::getInstance().openLogQue(open_log_que);
}
void setLogFormat(int format) {
    LoggerFilePrinter::getInstance().setDisplayFormat(format);
    LoggerCustPrinterMgr::getInstance().setDisplayFormat(format);
    LoggerConslPrintter::getInstance().setDisplayFormat(format);
}
void setLoggerLevel(int level ) {
    LoggerPrintMgr::getInstance().setLogLevel(level);
}

void setLogPrintMode (int mode) {
    LoggerPrintMgr::getInstance().addLogDevice(mode);
}

void clog(LOG_LEVEL level, const char* file, const char* fun, int line, const char* format, va_list ap) {
    char buf[MAX_SIZE] = { 0 };
    vsnprintf(buf,MAX_SIZE,format, ap);
    
    if (LOG_LEVEL::ERR == level) {
        hand_.err_.setProper(LogProper(level, file, fun, line));
        hand_.err_ << buf;
    }
    else {
        LogItem item;
        std::stringstream ss;
        ss << std::this_thread::get_id();
        item.property_ = std::move(LogProper(level, file, fun, line));
        item.log_ = buf;
        LoggerPrintMgr::getInstance().postLog(std::move(item));

    }
}

std::ostream& Info(const char* file, const char* fun, int line) {
    LogProper proper(LOG_LEVEL::INF, file, fun, line);
    hand_.inf_.setProper(std::move(proper));
    return hand_.inf_;
}

void Infof(const char* file, const char* fun, int line, const char* fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    clog(LOG_LEVEL::INF, file, fun, line, fmt, ap);
    va_end(ap);
}

std::ostream& Warn(const char* file,  const char* fun, int line) {
    LogProper proper(LOG_LEVEL::WAR, file, fun, line);
    hand_.war_.setProper(std::move(proper));
    return hand_.war_;
}

void Warnf(const char* file, const char* fun, int line, const char* fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    clog(LOG_LEVEL::WAR, file, fun, line, fmt, ap);
    va_end(ap);
}


std::ostream& Debug(const char* file, const char* fun, int line) {
    LogProper proper(LOG_LEVEL::BUG, file, fun, line);
    hand_.debug_.setProper(std::move(proper));
    return hand_.debug_;
}
void Debugf(const char* file, const char* fun, int line, const char* fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    clog(LOG_LEVEL::BUG, file, fun, line, fmt, ap);
    va_end(ap);
}

std::ostream& Error(const char* file, const char* fun, int line) {
    LogProper proper(LOG_LEVEL::ERR, file, fun, line);
    hand_.err_.setProper(std::move(proper));
    return hand_.err_;
}

void Errorf(const char* file, const char* fun, int line, const char* fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    clog(LOG_LEVEL::ERR, file, fun, line, fmt, ap);
    va_end(ap);
}


const ErrorTrace& GetLastErrorLog() {
    return hand_.err_.getLastError();
}
